/*
 *
 *  *
 *  *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  *  SPDX-License-Identifier: Apache-2.0
 *  *
 *
 */

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import axios from 'axios';
import PageBox from '@components/ui/PageBox';
import { formatUnixTime, strToJsonArray, decodeContractSignature, base64Decode } from '@src/utils/tools';
import detailstyle from '../detail.module.scss';
import liststyle from '../list.module.scss';
import { GetTxDetail } from '@src/utils/apis';
import { Form, Select, Switch, Table } from 'tea-component';
import { useParams } from 'react-router';
import { TxInfo } from '@src/models';
import { Link } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { RootReducer } from '@src/store';
import { EnumParamEncodeType, PARAMENCODEOPTIONS } from '@src/utils/enums';
import { hex } from '@src/utils/tools/hex';
import Web3 from 'web3';

// import Web3 from '@src/utils/tools/web3.js';

const web3 = new Web3();
type TxInfoDeCode = TxInfo | null;
const decodeFuncMap = {
  [EnumParamEncodeType.org]: (str:string) => str,
  [EnumParamEncodeType.utf8]: (str:string) => base64Decode(str),
  [EnumParamEncodeType.hex]: (str:string) => hex.encode(base64Decode(str)),
};
export default function TransactionDetail() {
  const { txId } = useParams();
  const { currentChain } = useSelector((state: RootReducer) => state.chainReducer);
  const chainId = useMemo(() => currentChain?.ChainId, [currentChain]);
  const authType = useMemo(() => currentChain?.AuthType, [currentChain]);
  const [detail, setDetail] = useState<TxInfoDeCode>(null);
  const [encodeType, setEncodeType] = useState(`${EnumParamEncodeType.utf8}`);
  const [openDecode, setOpenDecode] = useState(false);

  const decodeParam = useCallback((str) => {
    return (decodeFuncMap as any)[encodeType]?.(str);
  }, [encodeType]);
  const tryDecodeParam = useCallback(async (data) => {
    // console.log(data);
    const ContractParametersList:any[] = [];
    const promise = data.ContractParametersList.map(async (item:any) => {
      let value:{
        index: number;
        type: string;
        value: string;
      }[] = [];
      const v = base64Decode(item.value).replace(/^0x/, '');
      const contractHash = v.substr(0, 8);
      const hex = v.substring(8);
      if (hex) {
        const res = await axios.get(`/signatures/${contractHash}`);
        if (res.status === 200) {
          const abi = decodeContractSignature(res.data);
          if (abi) {
            const params = web3.eth.abi.decodeParameters(abi, hex);
            value = abi.map((i, index) => {
              return {
                index: index,
                type: i.type,
                value: params[index]
              };
            });
          }
        }
      }
      ContractParametersList.push({
        ...item,
        decodeValue: value
      });
    });
    await Promise.all(promise);
    console.log({
      ...data,
      ContractParametersList
    });
    setDetail({
      ...data,
      ContractParametersList
    });
  }, []);
  useEffect(() => {
    GetTxDetail({ ChainId: chainId, TxId: txId }).then((res) => {
      if (res.Data) {
        const data:TxInfoDeCode = res.Data;
        data.ContractParametersList = strToJsonArray(data.ContractParameters);
        data.ContractReadList = strToJsonArray(data.ContractRead);
        data.ContractWriteList = strToJsonArray(data.ContractWrite);
        data.EventList = strToJsonArray(data.Event);
        setDetail(data);
        if (data.RuntimeType.toUpperCase() === 'EVM') {
          tryDecodeParam(data);
        }
      }
    });
  }, [chainId, txId]);

  return (
    <PageBox title="交易详情">
      <div className={detailstyle.detail}>
        <Form.Title>所属区块信息</Form.Title>
        <Form hideLabel={false} fixedLabelWidth={100} layout="fixed">
          <Form.Item label="区块哈希">
            <Form.Text>
              {detail?.BlockHash && detail?.BlockHeight
                ? (
                  <Link to={`/${chainId}/block/${detail.BlockHeight}`}>{detail.BlockHash}</Link>
                )
                : (
                  detail?.BlockHash
                )}
              {!detail?.BlockHash && '--'}
            </Form.Text>
          </Form.Item>
          <Form.Item label="区块高度">
            <Form.Text>
              {detail?.BlockHeight
                ? (
                  <Link to={`/${chainId}/block/${detail.BlockHeight}`}>{detail.BlockHeight}</Link>
                )
                : (
                  '--'
                )}
            </Form.Text>
          </Form.Item>
        </Form>
        <Form.Title>交易信息</Form.Title>
        <Form hideLabel={false} fixedLabelWidth={100} layout="fixed">
          <Form.Item label="交易id">
            <Form.Text>{detail?.TxId || '--'}</Form.Text>
          </Form.Item>
          <Form.Item label="交易类型">
            <Form.Text>{detail?.TxType || '--'}</Form.Text>
          </Form.Item>
          <Form.Item label="交易状态">
            <Form.Text>{detail?.TxStatusCode || '--'}</Form.Text>
          </Form.Item>
          {authType === 'permissionedwithcert'
            ? (
              <>
                <Form.Item label="交易发送组织">
                  <Form.Text>{detail?.OrgId || '--'}</Form.Text>
                </Form.Item>
                <Form.Item label="交易发起用户">
                  <Form.Text>{detail?.Sender || '--'}</Form.Text>
                </Form.Item>
                <Form.Item label="发起用户地址">
                  <Form.Text>{detail?.UserAddr || '--'}</Form.Text>
                </Form.Item>
              </>
            )
            : (
              <Form.Item label="交易发起用户">
                <Form.Text>{detail?.UserAddr || '--'}</Form.Text>
              </Form.Item>
            )}
          <Form.Item label="GAS代付用户">
            <Form.Text>{detail?.Payer || '--'}</Form.Text>
          </Form.Item>
          <Form.Item label="交易发起时间">
            <Form.Text>{detail?.Timestamp ? formatUnixTime(detail.Timestamp) : '--'}</Form.Text>
          </Form.Item>
        </Form>
        <Form.Title>合约执行信息</Form.Title>
        <Form hideLabel={false} fixedLabelWidth={100} layout="fixed">
          <Form.Item label="目标合约">
            <Form.Text>
              {detail?.ContractName
                ? (
                  <Link to={`/${chainId}/contract/${detail.ContractName}`}>{detail.ContractName}</Link>
                )
                : (
                  '--'
                )}
            </Form.Text>
          </Form.Item>
          <Form.Item label="合约读写集哈希">
            <Form.Text>{detail?.RwSetHash || '--'}</Form.Text>
          </Form.Item>
          <Form.Item label="合约执行结果码">
            <Form.Text>{detail?.ContractResultCode === 0 ? 'ok' : 'fail'}</Form.Text>
          </Form.Item>

          <Form.Item label="合约执行信息">
            <Form.Text>{detail?.ContractMessage || '--'}</Form.Text>
          </Form.Item>
          <Form.Item label="GAS消耗量">
            <Form.Text>{detail?.GasUsed}</Form.Text>
          </Form.Item>
          <Form.Item label="合约调用方法">
            <Form.Text>{detail?.ContractMethod || '--'}</Form.Text>
          </Form.Item>
          <Form.Item
            label={
              <>
                合约调用入参
                <Select
                  value={encodeType}
                  onChange={setEncodeType}
                  style={{ marginTop: 8 }}
                  size="full"
                  appearance="button"
                  options={PARAMENCODEOPTIONS}
                ></Select>
              </>
            }
          >
            <Table
              className={liststyle.table}
              compact={false}
              records={detail?.ContractParametersList || []}
              recordKey="key"
              bordered={true}
              disableTextOverflow={true}
              columns={[
                {
                  key: 'index',
                  header: '#',
                  align: 'left',
                  width: 60,
                  render: (_item, _name, index) => index + 1,
                },
                {
                  key: 'key',
                  header: 'Key',
                  align: 'left',
                  width: 260,
                },
                {
                  key: 'value',
                  header: 'Value',
                  align: 'left',
                  render: ({ value, decodeValue }) => <>
                    {openDecode || <div className={liststyle.value_td}>{decodeParam(value)}</div>}
                    {!openDecode || <div className={liststyle.value_td_pre}>{
                      <Table
                        compact={false}
                        records={decodeValue || []}
                        recordKey="index"
                        bordered={true}
                        disableTextOverflow={true}
                        columns={[
                          {
                            key: 'index',
                            header: '#',
                            align: 'left',
                            width: 60,
                          },
                          {
                            key: 'type',
                            header: '类型',
                          },
                          {
                            key: 'value',
                            header: 'Value'
                          },
                        ]}
                      />
                    }</div>}
                    {!decodeValue || <Switch value={openDecode} onChange={setOpenDecode}>是否转码</Switch>}
                  </>,
                },
              ]}
            />
          </Form.Item>
          {!detail?.ContractReadList?.length || (
            <Form.Item label="合约读集">
              <Table
                className={liststyle.detail_table}
                compact={false}
                records={detail?.ContractReadList || []}
                recordKey="key"
                bordered={true}
                disableTextOverflow={true}
                columns={[
                  {
                    key: 'index',
                    header: '#',
                    align: 'left',
                    width: 60,
                    render: (item, name, index) => index + 1,
                  },
                  {
                    key: 'key',
                    header: 'Key',
                    align: 'left',
                    width: 260,
                  },
                  {
                    key: 'value',
                    header: 'Value',
                    align: 'left',
                    render: ({ value }) => <div className={liststyle.value_td}>{decodeParam(value)}</div>,
                  },
                ]}
              />
            </Form.Item>
          )}
          {!detail?.ContractWriteList?.length || (
            <Form.Item label="合约写集">
              <Table
                className={liststyle.detail_table}
                compact={false}
                records={detail?.ContractWriteList || []}
                recordKey="key"
                bordered={true}
                disableTextOverflow={true}
                columns={[
                  {
                    key: 'index',
                    header: '#',
                    align: 'left',
                    width: 60,
                    render: (item, name, index) => index + 1,
                  },
                  {
                    key: 'key',
                    header: 'Key',
                    align: 'left',
                    width: 260,
                  },
                  {
                    key: 'value',
                    header: 'Value',
                    align: 'left',
                    render: ({ value }) => <div className={liststyle.value_td}>{decodeParam(value)}</div>,
                  },
                ]}
              />
            </Form.Item>
          )}
          <Form.Item label="合约执行结果">
            <Form.Text>
              <pre className={detailstyle.pre}>{decodeParam(detail?.ContractResult)}</pre>
            </Form.Text>
          </Form.Item>
          {!detail?.EventList?.length || (
            <Form.Item label="合约事件">
              <Table
                className={liststyle.detail_table}
                compact={false}
                records={detail?.EventList || []}
                recordKey="key"
                bordered={true}
                disableTextOverflow={true}
                columns={[
                  {
                    key: 'index',
                    header: '#',
                    align: 'left',
                    width: 60,
                    render: (item, name, index) => index + 1,
                  },
                  {
                    key: 'key',
                    header: '事件主题',
                    align: 'left',
                    width: 260,
                  },
                  {
                    key: 'value',
                    header: '事件内容',
                    align: 'left',
                    render: ({ value }) => <div className={liststyle.value_td}>{decodeParam(value)}</div>,
                  },
                ]}
              />
            </Form.Item>
          )}
        </Form>
      </div>
    </PageBox>
  );
}
